/*
 * Copyright Notice. Copyright 2011 Northwestern University and Stanford
 * University (“caBIG® Participant”). AIM Template Enterprise Service conforms
 * to caBIG® technical specifications and is part of the caBIG® initiative. The
 * software subject to this notice and license includes human readable source
 * code form, machine readable, binary, object code form and related
 * documentation (the “caBIG® Software”).
 *
 * This caBIG® Software License (the “License”) is between the National Cancer
 * Institute (NCI) and You. “You (or “Your”) shall mean a person or an entity,
 * and all other entities that control, are controlled by, or are under common
 * control with the entity. “Control” for purposes of this definition means (i)
 * the direct or indirect power to cause the direction or management of such
 * entity, whether by contract or otherwise, or (ii) ownership of fifty percent
 * (50%) or more of the outstanding shares, or (iii) beneficial ownership of
 * such entity.
 *
 * Provided that You agree to the conditions described below, NCI grants You a
 * non-exclusive, worldwide, perpetual, fully-paid-up, no-charge, irrevocable,
 * transferable and royalty-free right and license in its rights in the caBIG®
 * Software, including any copyright or patent rights therein, to (i) use,
 * install, disclose, access, operate, execute, reproduce, copy, modify,
 * translate, market, publicly display, publicly perform, and prepare
 * derivative works of the caBIG® Software in any manner and for any purpose,
 * and to have or permit others to do so; (ii) make, have made, use, practice,
 * sell, and offer for sale, import, and/or otherwise dispose of caBIG®
 * Software (or portions thereof); (iii) distribute and have distributed to and
 * by third parties the caBIG® Software and any modifications and derivative
 * works thereof; and (iv) sublicense the foregoing rights set out in (i), (ii)
 * and (iii) to third parties, including the right to license such rights to
 * further third parties. For sake of clarity, and not by way of limitation,
 * NCI shall have no right of accounting or right of payment from You or Your
 * sublicensees for the rights granted under this License. This License is
 * granted at no charge to You. Your downloading, copying, modifying,
 * displaying, distributing or use of caBIG® Software constitutes acceptance of
 * all of the terms and conditions of this Agreement. If you do not agree to
 * such terms and conditions, you have no right to download, copy, modify,
 * display, distribute or use the caBIG® Software.
 *
 * Your redistributions of the source code for the caBIG® Software must retain
 * the above copyright notice, this list of conditions and the disclaimer and
 * limitation of liability of Article 6 below. Your redistributions in object
 * code form must reproduce the above copyright notice, this list of conditions
 * and the disclaimer of Article 6 in the documentation and/or other materials
 * provided with the distribution, if any.
 *
 * Your end-user documentation included with the redistribution, if any, must
 * include the following acknowledgment: “This product includes software
 * developed by Danny Korenblum, Alan Snyder, Vitaliy Semeshko, Vladimir Kleper
 * and Pattanasak Mongkolwat, Northwestern University and Stanford University.”
 * If You do not include such end-user documentation, You shall include this
 * acknowledgment in the caBIG® Software itself, wherever such third-party
 * acknowledgments normally appear.
 *
 * You may not use the names “Northwestern University”, “Stanford University”,
 * “The National Cancer Institute”, “NCI”, “Cancer Bioinformatics Grid” or
 * “caBIG®” to endorse or promote products derived from this caBIG® Software.
 * This License does not authorize You to use any trademarks, service marks,
 * trade names, logos or product names of either caBIG® Participant, NCI or
 * caBIG®, except as required to comply with the terms of this License.
 *
 * For sake of clarity, and not by way of limitation, You are not prohibited by
 * this License from incorporating this caBIG® Software into Your proprietary
 * programs and into any third party proprietary programs. However, if You
 * incorporate the caBIG® Software into third party proprietary programs, You
 * agree that You are solely responsible for obtaining any permission from such
 * third parties required to incorporate the caBIG® Software into such third
 * party proprietary programs and for informing Your sublicensees, including
 * without limitation Your end-users, of their obligation to secure any
 * required permissions from such third parties before incorporating the caBIG®
 * Software into such third party proprietary software programs. In the event
 * that You fail to obtain such permissions, You agree to indemnify NCI for any
 * claims against NCI by such third parties, except to the extent prohibited by
 * law, resulting from Your failure to obtain such permissions.
 * For sake of clarity, and not by way of limitation, You may add Your own
 * copyright statement to Your modifications and to the derivative works, and
 * You may provide additional or different license terms and conditions in
 * Your sublicenses of modifications of the caBIG® Software, or any derivative
 * works of the caBIG® Software as a whole, provided Your use, reproduction,
 * and distribution of the Work otherwise complies with the conditions stated
 * in this License.
 *
 * THIS caBIG® SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES (INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE) ARE
 * DISCLAIMED. IN NO EVENT SHALL NCI OR THE NORTHWESTERN UNIVERSITY OR ITS
 * AFFILIATES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS caBIG® SOFTWARE, EVEN
 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package edu.stanford.isis.atb.ui.view.template.impl;

import static edu.stanford.isis.atb.ui.Const.HNT_ADD_ALLOWED_TERMS;
import static edu.stanford.isis.atb.ui.Const.HNT_CREATE_ALGORITHM_TYPE;
import static edu.stanford.isis.atb.ui.Const.HNT_CREATE_AN_ENTITY;
import static edu.stanford.isis.atb.ui.Const.HNT_CREATE_AN_ENTITY_CHAR;
import static edu.stanford.isis.atb.ui.Const.HNT_CREATE_CALCULATION;
import static edu.stanford.isis.atb.ui.Const.HNT_CREATE_CALC_TYPE;
import static edu.stanford.isis.atb.ui.Const.HNT_CREATE_CHAR_QUANT;
import static edu.stanford.isis.atb.ui.Const.HNT_CREATE_COMPONENT;
import static edu.stanford.isis.atb.ui.Const.HNT_CREATE_GEOM_SHAPE;
import static edu.stanford.isis.atb.ui.Const.HNT_CREATE_IMG_OBS;
import static edu.stanford.isis.atb.ui.Const.HNT_CREATE_IMG_OBS_CHAR;
import static edu.stanford.isis.atb.ui.Const.HNT_CREATE_INFERENCE;
import static edu.stanford.isis.atb.ui.Const.HNT_CREATE_INTERVAL;
import static edu.stanford.isis.atb.ui.Const.HNT_CREATE_NON_QUANT;
import static edu.stanford.isis.atb.ui.Const.HNT_CREATE_NUMERICAL;
import static edu.stanford.isis.atb.ui.Const.HNT_CREATE_QST_TYPE;
import static edu.stanford.isis.atb.ui.Const.HNT_CREATE_QUANTILE;
import static edu.stanford.isis.atb.ui.Const.HNT_CREATE_SCALE;
import static edu.stanford.isis.atb.ui.Const.HNT_CREATE_TAG;
import static edu.stanford.isis.atb.ui.Const.HNT_DELETE_ALGORITHM_TYPE;
import static edu.stanford.isis.atb.ui.Const.HNT_DELETE_ALLOWED_TERM;
import static edu.stanford.isis.atb.ui.Const.HNT_DELETE_AN_ENTITY;
import static edu.stanford.isis.atb.ui.Const.HNT_DELETE_AN_ENTITY_CHAR;
import static edu.stanford.isis.atb.ui.Const.HNT_DELETE_CALCULATION;
import static edu.stanford.isis.atb.ui.Const.HNT_DELETE_CALC_TYPE;
import static edu.stanford.isis.atb.ui.Const.HNT_DELETE_COMPONENT;
import static edu.stanford.isis.atb.ui.Const.HNT_DELETE_GEOM_SHAPE;
import static edu.stanford.isis.atb.ui.Const.HNT_DELETE_IMG_OBS;
import static edu.stanford.isis.atb.ui.Const.HNT_DELETE_IMG_OBS_CHAR;
import static edu.stanford.isis.atb.ui.Const.HNT_DELETE_QST_TYPE;
import static edu.stanford.isis.atb.ui.Const.HNT_DELETE_TAG;
import static edu.stanford.isis.atb.ui.Const.LBL_TEMPLATE_COMPONENTS;

import java.awt.Component;
import java.awt.Cursor;
import java.awt.FlowLayout;
import java.awt.Insets;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.tree.DefaultMutableTreeNode;

import edu.stanford.isis.atb.domain.template.Template;
import edu.stanford.isis.atb.ui.Const;
import edu.stanford.isis.atb.ui.action.ActionSet;
import edu.stanford.isis.atb.ui.action.Command;
import edu.stanford.isis.atb.ui.action.CommandAction;
import edu.stanford.isis.atb.ui.model.tree.TemplateNodeType;
import edu.stanford.isis.atb.ui.model.tree.TemplateNodeValue;
import edu.stanford.isis.atb.ui.view.AbstractView;
import edu.stanford.isis.atb.ui.view.CanShowEditForm;
import edu.stanford.isis.atb.ui.view.resources.MiscImageBundle;
import edu.stanford.isis.atb.ui.view.resources.ToolBarImageBundle;
import edu.stanford.isis.atb.ui.view.template.TemplateEditorView;
import edu.stanford.isis.atb.ui.view.template.TemplateTreeManager;
import edu.stanford.isis.atb.ui.view.template.rules.TemplateModificationRules;
import edu.stanford.isis.atb.ui.view.widget.ScrollableBlockWIthToolbar;
import edu.stanford.isis.atb.ui.view.widget.tree.AbstractTree.NodeSelectionListener;
import edu.stanford.isis.atb.ui.view.widget.tree.TemplateTree;

/**
 * @author Vitaliy Semeshko
 */
public class TemplateEditorViewImpl extends AbstractView implements TemplateEditorView {

	private CanShowEditForm editFormManager;
	
	private ScrollableBlockWIthToolbar root = new ScrollableBlockWIthToolbar();

	private TemplateTree tree = new TemplateTree();

	private TemplateTreeManager treeManager = new TemplateTreeManagerImpl(tree);
	
	private ToolBarImageBundle images = ToolBarImageBundle.getInstance();
	
	private MiscImageBundle miscImages = MiscImageBundle.getInstance();

	private TemplateModificationRules modificationRules = new TemplateModificationRules();
	
	private Map<TemplateNodeType, Command> formShowCommands = new HashMap<TemplateNodeType, Command>();
	
	private List<ActionSet> actions = new ArrayList<ActionSet>();
	private ActionSet templateActions = new ActionSet();
	private ActionSet componentActions = new ActionSet();
	private ActionSet qstTypeActions = new ActionSet();
	private ActionSet geomShapeActions = new ActionSet();
	private ActionSet calculationActions = new ActionSet();
	private ActionSet calcTypeActions = new ActionSet();
	private ActionSet algorithmTypeActions = new ActionSet();
	private ActionSet tagActions = new ActionSet();
	private ActionSet tagNameActions = new ActionSet();
	private ActionSet termActions = new ActionSet();
	private ActionSet termWithQuantActions = new ActionSet();
	private ActionSet anatomicEntityActions = new ActionSet();
	private ActionSet anatomicEntityCharActions = new ActionSet();
	private ActionSet inferenceActions = new ActionSet();
	private ActionSet nonQuantActions = new ActionSet();
	private ActionSet imgObsActions = new ActionSet();
	private ActionSet imgObsCharActions = new ActionSet();
	private ActionSet charQuantificationActions = new ActionSet();
	
	private Map<TemplateNodeType, ActionSet> nodeActions = new HashMap<TemplateNodeType, ActionSet>();
	
	public TemplateEditorViewImpl() {
		root.setCaptionText(LBL_TEMPLATE_COMPONENTS);
		root.setMainComponent(tree);

		initTree();
		
		initNodeActions();
		
		actions.add(templateActions);
		actions.add(componentActions);
		actions.add(qstTypeActions);
		actions.add(geomShapeActions);
		actions.add(tagActions);
		actions.add(tagNameActions);
		actions.add(calculationActions);
		actions.add(calcTypeActions);
		actions.add(algorithmTypeActions);
		actions.add(termActions);
		actions.add(termWithQuantActions);
		actions.add(anatomicEntityActions);
		actions.add(anatomicEntityCharActions);
		actions.add(inferenceActions);
		actions.add(nonQuantActions);
		actions.add(imgObsActions);
		actions.add(imgObsCharActions);
		actions.add(charQuantificationActions);
		
		initExpandCollapseActions();
		initTemplateActions();
		initComponentActions();
		initQuestionTypeActions();
		initGeomShapeActions();
		initCalculationActions();
		initTagActions();
		initAllowedTermActions();
		initAnatomicEntityActions();
		initAnatomicEntityCharActions();
		initInferenceActions();
		initNonQuantifiableActions();
		initImgObsActions();
		initImgObsCharActions();
		initCharQuantificationActions();
	}

	public void setEditFormManager(CanShowEditForm editFormManager) {
		this.editFormManager = editFormManager;
	}
	
	private void initTree() {
		tree.enableContextMenu();
		
		tree.addNodeSelectionListener(new NodeSelectionListener<TemplateNodeValue>() {
			@Override
			public void onNodeSelected(TemplateNodeValue nodeValue) {
				ActionSet actions = nodeActions.get(nodeValue.getNodeType());
				
				// show/hide form
				Command showFormCommand = formShowCommands.get(nodeValue.getNodeType());
				if (showFormCommand != null) {
					showFormCommand.execute();
				} else {
					// hide edit form if no form to show
					hideEditForm();
				}
				
				tree.getContextMenu().removeAll();
				root.clearToolBar();
				
				if (actions != null) {
					// apply rules according to the node state
					modificationRules.applyRulesForNode(nodeValue, actions);
					
					// add actions to the toolbar and context menu 
					for (CommandAction action : actions.getAll()) {
						root.addToolBarAction(action);
						tree.getContextMenu().add(action);
					}
				}
			}
		});
	}
	
	private void initNodeActions() {
		nodeActions.put(TemplateNodeType.TEMPLATE, templateActions);
		nodeActions.put(TemplateNodeType.COMPONENT, componentActions);
		nodeActions.put(TemplateNodeType.QUESTION_TYPE, qstTypeActions);
		nodeActions.put(TemplateNodeType.GEOMETRIC_SHAPE, geomShapeActions);
		nodeActions.put(TemplateNodeType.CALCULATION, calculationActions);
		nodeActions.put(TemplateNodeType.CALCULATION_TYPE, calcTypeActions);
		nodeActions.put(TemplateNodeType.ALGORITHM_TYPE, algorithmTypeActions);
		nodeActions.put(TemplateNodeType.TAG, tagActions);
		nodeActions.put(TemplateNodeType.TAG_NAME, tagNameActions);
		nodeActions.put(TemplateNodeType.ALLOWED_TERM, termActions);
		nodeActions.put(TemplateNodeType.ALLOWED_TERM_WITH_QUANTIFICATION, termWithQuantActions);
		nodeActions.put(TemplateNodeType.ANATOMIC_ENTITY, anatomicEntityActions);
		nodeActions.put(TemplateNodeType.ANATOMIC_ENTITY_CHARACTERISTIC, anatomicEntityCharActions);
		nodeActions.put(TemplateNodeType.INFERENCE, inferenceActions);
		nodeActions.put(TemplateNodeType.NON_QUANTIFIABLE, nonQuantActions);
		nodeActions.put(TemplateNodeType.IMAGING_OBSERVATION, imgObsActions);
		nodeActions.put(TemplateNodeType.IMAGING_OBSERVATION_CHARACTERISTIC, imgObsCharActions);
		nodeActions.put(TemplateNodeType.CHARACTERISTIC_QUANTIFICATION, charQuantificationActions);
	}
	
	private void initExpandCollapseActions() {
		JPanel holder = new JPanel(new FlowLayout());
		holder.setBorder(new EmptyBorder(new Insets(0, 0, 0, 6)));
		
		JLabel expand = new JLabel(miscImages.getExpandIcon().loadIcon());
		expand.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
		
		expand.addMouseListener(new MouseAdapter() { 
			public void mouseClicked(MouseEvent e) {
				for (int i = 0; i < tree.getRowCount(); i++) {
					tree.expandRow(i);
				}
			}
		});
		
		JLabel collapse = new JLabel(miscImages.getCollapseIcon().loadIcon());
		collapse.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
		
		collapse.addMouseListener(new MouseAdapter() { 
			public void mouseClicked(MouseEvent e) {
				for (int i = tree.getRowCount() - 1; i > 0 ; i--) {
					tree.collapseRow(i);
				}
			}
		});
		
		holder.add(expand);
		holder.add(collapse);
		
		root.addHeaderRightComponent(holder);
	}
	
	private void initTemplateActions() {
		CommandAction createComponent = new CommandAction(HNT_CREATE_COMPONENT, images.getCreateComponentIcon());
		templateActions.add(TemplateAction.CREATE_COMPONENT, createComponent);
		
		CommandAction createTag = new CommandAction(HNT_CREATE_TAG, images.getCreateTagIcon());
		templateActions.add(TemplateAction.CREATE_TAG, createTag);
	}
	
	private void initComponentActions() {
		CommandAction deleteComponent = new CommandAction(HNT_DELETE_COMPONENT, images.getDeleteIcon());
		componentActions.add(ComponentAction.DELETE, deleteComponent);
		
		CommandAction createQstType = new CommandAction(HNT_CREATE_QST_TYPE, images.getCreateQuestionTypeIcon());
		componentActions.add(ComponentAction.CREATE_QST_TYPE, createQstType);
		
		CommandAction createAnEntity = new CommandAction(HNT_CREATE_AN_ENTITY, images.getCreateAnatomicEntityIcon());
		componentActions.add(ComponentAction.CREATE_AN_ENTITY, createAnEntity);
		
		CommandAction createImgObs = new CommandAction(HNT_CREATE_IMG_OBS, images.getCreateImageObservationIcon());
		componentActions.add(ComponentAction.CREATE_IMG_OBS, createImgObs);
		
		CommandAction createInference = new CommandAction(HNT_CREATE_INFERENCE, images.getCreateInferenceIcon());
		componentActions.add(ComponentAction.CREATE_INFERENCE, createInference);
		
		CommandAction createCalculation = new CommandAction(HNT_CREATE_CALCULATION, images.getCreateCalculationIcon());
		componentActions.add(ComponentAction.CREATE_CALCULATION, createCalculation);
		
		CommandAction createGeomShape = new CommandAction(HNT_CREATE_GEOM_SHAPE, images.getCreateShapeIcon());
		componentActions.add(ComponentAction.CREATE_GEOM_SHAPE, createGeomShape);
		
		CommandAction addAllowedTerms = new CommandAction(HNT_ADD_ALLOWED_TERMS, images.getCreateAllowedTermIcon());
		componentActions.add(ComponentAction.ADD_ALLOWED_TERMS, addAllowedTerms);
	}

	private void initQuestionTypeActions() {
		CommandAction delete = new CommandAction(HNT_DELETE_QST_TYPE, images.getDeleteIcon());
		qstTypeActions.add(QuestionTypeAction.DELETE, delete);
	}
	
	private void initGeomShapeActions() {
		CommandAction delete = new CommandAction(HNT_DELETE_GEOM_SHAPE, images.getDeleteIcon());
		geomShapeActions.add(GeometricShapeAction.DELETE, delete);
	}
	
	private void initCalculationActions() {
		// calculation
		CommandAction deleteCalculation = new CommandAction(HNT_DELETE_CALCULATION, images.getDeleteIcon());
		calculationActions.add(СalculationAction.DELETE, deleteCalculation);
		
		CommandAction createCalcType = new CommandAction(HNT_CREATE_CALC_TYPE, images.getCreateCalcTypeIcon());
		calculationActions.add(СalculationAction.CREATE_CALC_TYPE, createCalcType);
		
		// calc type
		CommandAction deleteCalcType = new CommandAction(HNT_DELETE_CALC_TYPE, images.getDeleteIcon());
		calcTypeActions.add(CalculationTypeAction.DELETE, deleteCalcType);
		
		CommandAction createAlgorithmType = new CommandAction(HNT_CREATE_ALGORITHM_TYPE, 
				images.getCreateAlgorithmTypeIcon());
		calcTypeActions.add(CalculationTypeAction.CREATE_ALGORITHM_TYPE, createAlgorithmType);
		
		// algorithm type
		CommandAction deleteAlgorithmType = new CommandAction(HNT_DELETE_ALGORITHM_TYPE, images.getDeleteIcon());
		algorithmTypeActions.add(AlgorithmTypeAction.DELETE, deleteAlgorithmType);
	}
	
	private void initAnatomicEntityActions() {
		CommandAction delete = new CommandAction(HNT_DELETE_AN_ENTITY, images.getDeleteIcon());
		anatomicEntityActions.add(AnatomicEntityAction.DELETE, delete);
		
		CommandAction createChar = new CommandAction(HNT_CREATE_AN_ENTITY_CHAR, images.getCreateAnatomicEntityCharIcon());
		anatomicEntityActions.add(AnatomicEntityAction.CREATE_AN_ENTITY_CHAR, createChar);
	}
	
	private void initAnatomicEntityCharActions() {
		CommandAction delete = new CommandAction(HNT_DELETE_AN_ENTITY_CHAR, images.getDeleteIcon());
		anatomicEntityCharActions.add(AnatomicEntityCharAction.DELETE, delete);
		
		CommandAction createQstType = new CommandAction(HNT_CREATE_QST_TYPE, images.getCreateQuestionTypeIcon());
		anatomicEntityCharActions.add(AnatomicEntityCharAction.CREATE_QST_TYPE, createQstType);
		
		CommandAction addAllowedTerms = new CommandAction(HNT_ADD_ALLOWED_TERMS, images.getCreateAllowedTermIcon());
		anatomicEntityCharActions.add(AnatomicEntityCharAction.ADD_ALLOWED_TERMS, addAllowedTerms);
	}
	
	private void initImgObsActions() {
		CommandAction delete = new CommandAction(HNT_DELETE_IMG_OBS, images.getDeleteIcon());
		imgObsActions.add(ImagingObservationAction.DELETE, delete);
		
		CommandAction createChar = new CommandAction(HNT_CREATE_IMG_OBS_CHAR, images.getCreateAnatomicEntityCharIcon());
		imgObsActions.add(ImagingObservationAction.CREATE_IMG_OBS_CHAR, createChar);
	}
	
	private void initImgObsCharActions() {
		CommandAction delete = new CommandAction(HNT_DELETE_IMG_OBS_CHAR, images.getDeleteIcon());
		imgObsCharActions.add(ImagingObservationCharAction.DELETE, delete);
		
		CommandAction createQstType = new CommandAction(HNT_CREATE_QST_TYPE, images.getCreateQuestionTypeIcon());
		imgObsCharActions.add(ImagingObservationCharAction.CREATE_QST_TYPE, createQstType);
		
		CommandAction addAllowedTerms = new CommandAction(HNT_ADD_ALLOWED_TERMS, images.getCreateAllowedTermIcon());
		imgObsCharActions.add(ImagingObservationCharAction.ADD_ALLOWED_TERMS, addAllowedTerms);
	}
	
	private void initAllowedTermActions() {
		// simple allowed term
		CommandAction deleteTerm = new CommandAction(HNT_DELETE_ALLOWED_TERM, images.getDeleteIcon());
		termActions.add(AllowedTermAction.DELETE, deleteTerm);
		
		CommandAction createNonQuantifiable = new CommandAction(HNT_CREATE_NON_QUANT, 
				images.getCreateNonQuantifiableIcon());
		termActions.add(AllowedTermAction.CREATE_NON_QUANT, createNonQuantifiable);
		
		// allowed term with quantification
		CommandAction deleteTermWithQuant = new CommandAction(HNT_DELETE_ALLOWED_TERM, images.getDeleteIcon());
		termWithQuantActions.add(AllowedTermWithQuantAction.DELETE, deleteTermWithQuant);
		
		CommandAction createCharQuant = new CommandAction(HNT_CREATE_CHAR_QUANT, 
				images.getCreateCharacteristicQuantificationIcon());
		termWithQuantActions.add(AllowedTermWithQuantAction.CREATE_CHAR_QUANT, createCharQuant);
	}
	
	private void initCharQuantificationActions() {
		CommandAction delete = new CommandAction(Const.HNT_DELETE_CHAR_QUANT, images.getDeleteIcon());
		charQuantificationActions.add(CharQuantificationAction.DELETE, delete);
		
		CommandAction createNonQuantifiable = new CommandAction(HNT_CREATE_NON_QUANT, 
				images.getCreateNonQuantifiableIcon());
		charQuantificationActions.add(CharQuantificationAction.CREATE_NON_QUANT, createNonQuantifiable);
		
		//TODO: icon
		CommandAction createScale = new CommandAction(HNT_CREATE_SCALE, images.getDeleteIcon());
		charQuantificationActions.add(CharQuantificationAction.CREATE_SCALE, createScale);
		
		//TODO: icon
		CommandAction createNumerical = new CommandAction(HNT_CREATE_NUMERICAL, images.getDeleteIcon());
		charQuantificationActions.add(CharQuantificationAction.CREATE_NUMERICAL, createNumerical);
		
		//TODO: icon
		CommandAction createQuantile = new CommandAction(HNT_CREATE_QUANTILE, images.getDeleteIcon());
		charQuantificationActions.add(CharQuantificationAction.CREATE_QUANTILE, createQuantile);
		
		//TODO: icon
		CommandAction createInterval = new CommandAction(HNT_CREATE_INTERVAL, images.getDeleteIcon());
		charQuantificationActions.add(CharQuantificationAction.CREATE_INTERVAL, createInterval);
	}
	
	private void initNonQuantifiableActions() {
		CommandAction delete = new CommandAction(Const.HNT_DELETE_NON_QUANT, images.getDeleteIcon());
		nonQuantActions.add(NonQuantifiableAction.DELETE, delete);
	}
	
	private void initInferenceActions() {
		CommandAction deleteInference = new CommandAction(Const.HNT_DELETE_INFERENCE, images.getDeleteIcon());
		inferenceActions.add(InferenceAction.DELETE, deleteInference);
		
		CommandAction createQuestType = new CommandAction(HNT_CREATE_QST_TYPE, images.getCreateQuestionTypeIcon());
		inferenceActions.add(InferenceAction.CREATE_QST_TYPE, createQuestType);
	}
	
	private void initTagActions() {
		// tag
		CommandAction deleteTag = new CommandAction(HNT_DELETE_TAG, images.getDeleteIcon());
		tagActions.add(TagAction.DELETE, deleteTag);
	}
	
	@Override
	public Component asComponent() {
		return root;
	}

	@Override
	public void setActiveTemplate(Template template) {
		treeManager.setTemplate(template);
	}

	@SuppressWarnings("unchecked")
	@Override
	public <T> T getSelectedNodeValue() {
		DefaultMutableTreeNode node = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent();
		TemplateNodeValue nodeValue = ((TemplateNodeValue) node.getUserObject());
		return (T) nodeValue.getValue();
	}
	
	@Override
	public void setCommand(Object actionKey, Command command) {
		for (ActionSet actionSet : actions) {
			CommandAction action = actionSet.get(actionKey);
			if (action != null) {
				action.setCommand(command);
				break;
			}
		}
	}
	
	@Override
	public void setShowFormCommand(TemplateNodeType nodeType, Command command) {
		formShowCommands.put(nodeType, command);
	}
	
	// view

	@Override
	public void hideEditForm() {
		editFormManager.hideEditForm();
	}

	@Override
	public void showEditForm(Component c) {
		editFormManager.showEditForm(c);
	}
	
	@Override
	public void clear() {
		treeManager.clear();
		root.clearToolBar();
		tree.getContextMenu().removeAll();		
	}

	@Override
	public void selectRootNode() {
		treeManager.selectRootNode();
	}

	@Override
	public TemplateTreeManager getTreeManager() {
		return treeManager;
	}

}
